﻿@page "/backup"
@rendermode InteractiveServer
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.Authorization
@using HtERP.Data
@using HtERP.Services
@inject IDbBackupService DbBackupService
@inject IConfigService ConfigService
@inject IFileUploadService FileUploadService
@inject IBackupScheduleService ScheduleService
@inject ILogger<Backup> Logger

<RedirectToLogin />

<PageTitle>数据库备份</PageTitle>

<div class="container">
    <h1>数据库备份</h1>

    @if (BackupResult != null)
    {
        <div class="alert mt-4 @(BackupResult.Success ? "alert-success" : "alert-danger")">
            @BackupResult.Message
        </div>
    }

    @if (!string.IsNullOrEmpty(UploadResultMessage))
    {
        <div class="alert mt-4 @(IsUploadSuccess ? "alert-success" : "alert-danger")">
            @UploadResultMessage
        </div>
    }

    <div class="card mt-1">
        <div class="card-header">
            备份设置
        </div>
        <div class="card-body">
               
            <div class="form-group mt-3">
                <label for="backupPath">备份路径</label>
                <input type="text" class="form-control" id="backupPath" @bind="BackupPath" />
            </div>
            
            <div class="form-group mt-3">
                <label for="backupName">备份文件名</label>
                <input type="text" class="form-control" id="backupName" @bind="BackupName" />
            </div>
            
            <div class="form-group mt-3">
                <label for="compress">压缩备份</label>
                <input type="checkbox" class="form-check-input ml-2" @bind="Compress" id="compress" />
            </div>
            
            <div class="form-group mt-3">
                <label for="uploadToServer">上传到服务器</label>
                <input type="checkbox" class="form-check-input ml-2" @bind="UploadToServer" id="uploadToServer" />
            </div>
            
            <div class="mt-4">
                <button class="btn btn-primary mr-2" @onclick="ExecuteBackup" disabled="@IsBackupRunning">
                    @(IsBackupRunning ? "备份中..." : "启动备份")
                </button>
                <button class="btn btn-secondary" @onclick="SaveSettings" disabled="@IsBackupRunning">
                    保存设置
                </button>
            </div>
            
            @if (!string.IsNullOrEmpty(SaveSettingsResult))
            {
                <div class="alert mt-3 @(IsSaveSettingsSuccess ? "alert-success" : "alert-danger")">
                    @SaveSettingsResult
                </div>
            }
        </div>
    </div>
    
    @if (UploadToServer) 
    {
        <div class="card mt-1">
            <div class="card-header">
                服务器上传设置
            </div>
            <div class="card-body">
                <div class="form-group">
                    <label for="serverUrl">服务器地址</label>
                    <input type="text" class="form-control" id="serverUrl" @bind="ServerUrl" placeholder="https://localhost:5001/api" />
                </div>
                
                <div class="form-group mt-3">
                    <label for="serverUsername">用户名</label>
                    <input type="text" class="form-control" id="serverUsername" @bind="ServerUsername" />
                </div>
                
                <div class="form-group mt-3">
                    <label for="serverPassword">密码</label>
                    <input type="password" class="form-control" id="serverPassword" @bind="ServerPassword" />
                </div>
                
            </div>
        </div>
    }
    
</div>

@code {
    private const string MySQL = "MySQL";
    private const string SQLServer = "SQLServer";
    private const string PostgreSQL = "PostgreSQL";
    private const string SQLite = "SQLite";
    private const string Access = "Access";
    
    private string SelectedDbType { get; set; } = MySQL;
    private string ConnectionString { get; set; } = "server=localhost;database=test;user=root;password=password;";
    private string BackupPath { get; set; } = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "DatabaseBackups");
    private string BackupName { get; set; } = string.Empty;
    private bool Compress { get; set; } = true;
    private bool IsBackupRunning { get; set; } = false;
    private BackupResult? BackupResult { get; set; } = null;
    private string SaveSettingsResult { get; set; } = string.Empty;
    private bool IsSaveSettingsSuccess { get; set; } = false;
    
    // 上传相关属性
    private bool UploadToServer { get; set; } = false;
    private string ServerUrl { get; set; } = "https://localhost:5001/api";
    private string ServerUsername { get; set; } = string.Empty;
    private string ServerPassword { get; set; } = string.Empty;
    private string UploadResultMessage { get; set; } = string.Empty;
    private bool IsUploadSuccess { get; set; } = false;
    
    // 备份设置数据结构
    private class BackupSettings
    {
        public string DatabaseType { get; set; }
        public string ConnectionString { get; set; }
        public string BackupPath { get; set; }
        public bool Compress { get; set; }
        // 上传相关设置
        public bool UploadToServer { get; set; }
        public string? ServerUrl { get; set; }
        public string? ServerUsername { get; set; }
        public string? ServerPassword { get; set; }
        public int LargeFileThresholdMB { get; set; }
        public int ChunkSizeMB { get; set; }
    }
    
    protected override async Task OnInitializedAsync()
    {
        // 页面加载时加载保存的设置
        await LoadBackupSettings();
        
        // 初始化备份文件名
        UpdateBackupFileName();
    }
        
    // 根据数据库类型更新备份文件名
    private void UpdateBackupFileName()
    {
        string baseName = Path.GetFileNameWithoutExtension(BackupName);
        
        // 如果没有基础名称或基础名称只是默认的日期格式，则生成新的基础名称
        if (string.IsNullOrEmpty(baseName) || 
            baseName.StartsWith("backup_") && baseName.Length == 22) // 检查是否是默认格式 backup_yyyyMMdd_HHmmss
        {
            baseName = GenerateBackupBaseName();
        }
        
        // 根据数据库类型设置正确的扩展名
        string extension = GetExtensionByDbType(SelectedDbType);
        
        BackupName = $"{baseName}{extension}";
    }
    
    // 生成备份基础名称
    private string GenerateBackupBaseName()
    {
        return $"backup_{DateTime.Now:yyyyMMdd_HHmmss}";
    }
    
    // 根据数据库类型获取对应的文件扩展名
    private string GetExtensionByDbType(string dbType)
    {
        switch (dbType)
        {
            case MySQL:
                return ".sql";
            case SQLServer:
                return ".bak";
            case PostgreSQL:
                return ".dump";
            case SQLite:
                return ".db";
            case Access:
                return ".accdb";
            default:
                return ".bak";
        }
    }
    
    private Task LoadBackupSettings()
    {
        try
        {
            var settings = ConfigService.GetConfig<BackupSettings>("BackupPageSettings");
            if (settings != null)
            {
                SelectedDbType = settings.DatabaseType ?? MySQL;
                ConnectionString = settings.ConnectionString ?? "server=localhost;database=test;user=root;password=password;";
                BackupPath = settings.BackupPath ?? Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "DatabaseBackups");
                Compress = settings.Compress;
                // 加载上传设置
                UploadToServer = settings.UploadToServer;
                ServerUrl = settings.ServerUrl ?? "https://localhost:5001/api";
                ServerUsername = settings.ServerUsername ?? string.Empty;
                ServerPassword = settings.ServerPassword ?? string.Empty;
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("加载备份设置失败: " + ex.Message);
        }
        return Task.CompletedTask;
    }
    
    private async Task SaveBackupSettings()
    {
        try
        {
            // 验证必填字段
            if (string.IsNullOrEmpty(SelectedDbType) ||
                string.IsNullOrEmpty(ConnectionString) ||
                string.IsNullOrEmpty(BackupPath))
            {
                throw new Exception("请填写所有必填字段");
            }
            
            // 验证备份路径
            if (!Directory.Exists(BackupPath))
            {
                try
                {
                    Directory.CreateDirectory(BackupPath);
                }
                catch (Exception ex)
                {
                    throw new Exception("备份路径无效或无权限创建目录: " + ex.Message);
                }
            }
            
            var settings = new BackupSettings
            {
                DatabaseType = SelectedDbType,
                ConnectionString = ConnectionString,
                BackupPath = BackupPath,
                Compress = Compress,
                // 保存上传设置
                UploadToServer = UploadToServer,
                ServerUrl = ServerUrl,
                ServerUsername = ServerUsername,
                ServerPassword = ServerPassword
            };
            
            await ConfigService.UpdateConfigAsync("BackupPageSettings", settings);
        }
        catch (Exception)
        {
            throw;
        }
    }
    
    private async Task SaveSettings()
    {
        try
        {
            await SaveBackupSettings();
            SaveSettingsResult = "设置保存成功！";
            IsSaveSettingsSuccess = true;
            
            // 5秒后清除消息
            await Task.Delay(5000);
            SaveSettingsResult = string.Empty;
            IsSaveSettingsSuccess = false;
        }
        catch (Exception ex)
        {
            SaveSettingsResult = "保存失败: " + ex.Message;
            IsSaveSettingsSuccess = false;
            
            // 5秒后清除消息
            await Task.Delay(5000);
            SaveSettingsResult = string.Empty;
            IsSaveSettingsSuccess = false;
        }
    }
    
    private async Task ExecuteBackup()
    {
        IsBackupRunning = true;
        BackupResult = null!;
        SaveSettingsResult = null;
        UploadResultMessage = string.Empty;
        
        try
        {
            // 构建完整的备份文件路径
            string fullBackupPath = Path.Combine(BackupPath, $"{BackupName}");
            
            // 调用备份服务并获取实际的备份文件路径
            var result = await DbBackupService.BackupDatabaseAsync(SelectedDbType, ConnectionString, fullBackupPath, Compress);
            BackupResult = result;
            
            // 备份成功后保存当前设置
            if (result.Success && !string.IsNullOrEmpty(result.BackupFilePath))
            {
                await SaveBackupSettings();
                
                // 如果启用了上传，上传备份文件
                if (UploadToServer && !string.IsNullOrEmpty(ServerUrl))
                {
                    await UploadBackupFileAsync(result.BackupFilePath);
                }
                
                // 创建并保存备份历史记录
                await CreateBackupHistoryRecord(result, fullBackupPath);
            }
        }
        catch (Exception ex)
        {
            BackupResult = new BackupResult
            {
                Success = false,
                Message = "备份失败: " + ex.Message
            };
            
            // 创建失败的备份历史记录
            await CreateBackupHistoryRecord(BackupResult, null);
        }
        finally
        {
            IsBackupRunning = false;
        }
    }
    
    private async Task UploadBackupFileAsync(string backupFilePath)
    {
        try
        {
            // 从连接字符串解析数据库名
            string databaseName = GetDatabaseNameFromConnectionString();
            
            // 创建UploadRequest对象
            var uploadRequest = new UploadRequest
            {
                FileName = string.IsNullOrEmpty(BackupName) ? "临时备份" : BackupName,
                FileSize = new FileInfo(backupFilePath).Length,
                FileType = Path.GetExtension(backupFilePath).TrimStart('.'),
                UploadTime = DateTime.Now,
                DatabaseName = databaseName,
                DatabaseType = SelectedDbType,
                SourceMachine = Environment.MachineName,
                Description = $"Database backup for {databaseName}"
            };
            
            // 使用FileUploadService上传文件
            var uploadStatus = await FileUploadService.UploadFileAsync(backupFilePath, uploadRequest);
            
            if (uploadStatus.Completed)
            {
                UploadResultMessage = "文件上传成功！";
                IsUploadSuccess = true;
            }
            else
            {
                UploadResultMessage = string.IsNullOrEmpty(uploadStatus.ErrorMessage) ? "文件上传失败" : uploadStatus.ErrorMessage;
                IsUploadSuccess = false;
            }
        }
        catch (Exception ex)
        {
            UploadResultMessage = "上传文件时发生异常: " + ex.Message;
            IsUploadSuccess = false;
        }
        
        // 1秒后清除上传结果消息
        await Task.Delay(1000);
        UploadResultMessage = string.Empty;
        IsUploadSuccess = false;
    }
    
    /// <summary>
    /// 创建并保存备份历史记录
    /// </summary>
    private async Task CreateBackupHistoryRecord(BackupResult result, string? backupFilePath)
    {
        try
        {
            // 对于单次备份，创建一个临时的ScheduleId
            var temporaryScheduleId = Guid.NewGuid();
            
            // 创建备份历史记录
            var historyItem = new BackupHistory
            {
                Id = Guid.NewGuid(),
                ScheduleId = temporaryScheduleId, // 使用临时ID表示这是单次备份
                ScheduleName = "单次备份",
                BackupTime = DateTime.Now,
                IsSuccess = result.Success,
                BackupFileName = BackupName,
                BackupFilePath = result.Success ? result.BackupFilePath : null,
                Message = result.Message,
                DatabaseType = SelectedDbType,
                DatabaseName = GetDatabaseNameFromConnectionString()
            };
            
            // 如果备份成功，获取文件大小
            if (result.Success && !string.IsNullOrEmpty(result.BackupFilePath) && File.Exists(result.BackupFilePath))
            {
                var fileInfo = new FileInfo(result.BackupFilePath);
                historyItem.FileSize = fileInfo.Length;
            }
            
            // 添加上传状态信息
            if (UploadToServer && !string.IsNullOrEmpty(UploadResultMessage))
            {
                historyItem.Message += $"\n{UploadResultMessage}";
            }
            
            // 使用IBackupScheduleService中的AddBackupHistoryAsync方法添加备份历史记录
            var success = await ScheduleService.AddBackupHistoryAsync(historyItem);
            if (!success)
            {
                Logger.LogWarning("通过ScheduleService添加备份历史记录失败");
            }
            
            Logger.LogInformation("备份历史记录已保存: {Result}, File: {File}", result.Success ? "成功" : "失败", BackupName);
        }
        catch (Exception ex)
        {
            Logger.LogError(ex, "保存备份历史记录失败");
        }
    }
    
    /// <summary>
    /// 从连接字符串解析数据库名
    /// </summary>
    private string GetDatabaseNameFromConnectionString()
    {
        if (string.IsNullOrEmpty(ConnectionString))
            return "UnknownDatabase";
            
        try
        {
            // 根据不同的数据库类型使用不同的解析逻辑
            switch (SelectedDbType)
            {
                case MySQL:
                    return ExtractValueFromConnectionString(ConnectionString, "database=", ";");
                case SQLServer:
                    return ExtractValueFromConnectionString(ConnectionString, "Initial Catalog=", ";");
                case PostgreSQL:
                    return ExtractValueFromConnectionString(ConnectionString, "Database=", ";");
                case SQLite:
                case Access:
                    // 对于SQLite和Access，数据库名通常是文件路径
                    // 这里简单处理，返回文件名
                    string dataSource = ExtractValueFromConnectionString(ConnectionString, "Data Source=", ";");
                    if (!string.IsNullOrEmpty(dataSource))
                        return Path.GetFileNameWithoutExtension(dataSource);
                    return "UnknownDatabase";
                default:
                    return "UnknownDatabase";
            }
        }
        catch
        {
            return "UnknownDatabase";
        }
    }
    
    /// <summary>
    /// 从连接字符串中提取指定键的值
    /// </summary>
    private string ExtractValueFromConnectionString(string connectionString, string key, string delimiter)
    {
        if (string.IsNullOrEmpty(connectionString) || string.IsNullOrEmpty(key))
            return string.Empty;
            
        int keyIndex = connectionString.IndexOf(key, StringComparison.OrdinalIgnoreCase);
        if (keyIndex == -1)
            return string.Empty;
            
        int startIndex = keyIndex + key.Length;
        int endIndex = connectionString.IndexOf(delimiter, startIndex);
        
        if (endIndex == -1)
            endIndex = connectionString.Length;
            
        return connectionString.Substring(startIndex, endIndex - startIndex).Trim();
    }
    
    /// <summary>
    /// 检查并启动自动上传服务
    /// </summary>


}